package com.ruoyi.web.controller.app;

import com.ruoyi.canteen.domain.ConsumTransaction;
import com.ruoyi.canteen.domain.OrderRecord;
import com.ruoyi.canteen.domain.Setmeal;
import com.ruoyi.canteen.domain.dto.CarouseDto;
import com.ruoyi.canteen.domain.dto.MealRecordDTO;
import com.ruoyi.canteen.domain.vo.MealDetailVO;
import com.ruoyi.canteen.domain.vo.MealListVo;
import com.ruoyi.canteen.domain.WeeklySetmeal;
import com.ruoyi.canteen.domain.vo.MealStatisticsVO;
import com.ruoyi.canteen.domain.vo.WeekDayVo;
import com.ruoyi.canteen.mapper.MainMapper;
import com.ruoyi.canteen.service.IOrderRecordService;
import com.ruoyi.canteen.service.ISetmealService;
import com.ruoyi.canteen.service.IWeeklySetmealService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.websocket.WebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @author: 杨祥
 * @date: 2025/03/26/13:03
 * @description:
 */
@RestController()
public class MainController extends BaseController {
    @Autowired
    private ISysUserService userService;
    public static final Logger log = LoggerFactory.getLogger(MainController.class);
    @Autowired
    private ISetmealService setmealService;
    @Autowired
    private IWeeklySetmealService weeklySetmealService;
    @Autowired
    private IOrderRecordService orderRecordService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private MainMapper mainMapper;

    @PostMapping("/getMealTableList")
    public AjaxResult getMealTableList(@RequestBody Map<String, String> params) {
        String weekScope = params.get("weekScope"); // "本周" or "下周"
        Long userId = params.get("userId") == null ? null : Long.parseLong(params.get("userId"));

        // 获取今天是周几（1=周一，7=周日）
        LocalDate today = LocalDate.now();
        int todayIndex = today.getDayOfWeek().getValue();

        // 计算本周/下周的周一
        LocalDate monday = "下周".equals(weekScope)
                ? today.plusDays(8 - todayIndex)
                : today.minusDays(todayIndex - 1);

        // 构造本周/下周的 dayNumbers（周一至周五）
        List<Long> dayNumbers = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            dayNumbers.add(Long.parseLong(
                    monday.plusDays(i).format(DateTimeFormatter.ofPattern("yyyyMMdd"))
            ));
        }

        // 查询数据
        List<WeekDayVo> result = weeklySetmealService.selectMealTableListByDayNumbers(userId, dayNumbers);
        return AjaxResult.success(result);
    }

    @PostMapping("/submitOrder")
    public AjaxResult submitOrder(@RequestBody Map<String, String> params, HttpServletRequest request) {
        Long weeklySetMealId = Long.valueOf(params.get("packageId"));
        Long dayNumber = Long.valueOf(params.get("dayNumber"));
        Long userId = Long.valueOf(params.get("userId"));
        String mealType = params.get("mealType");
        String weekDay = params.get("weekDay");
        if (checkCancelCondition(dayNumber, mealType) == 0) {
            return AjaxResult.error("当前时间不可更换报餐");
        }
        if (checkCount(userId) <= 0) {
            return AjaxResult.error("次数不足无法报餐,请联系陈浩添加");
        }
        List<OrderRecord> records = orderRecordService.selectRecordByUMId(userId, dayNumber);
        if (!CollectionUtils.isEmpty(records)) {
            if (records.size() == 1 && Objects.equals(records.get(0).getMealType(), mealType)) {
                OrderRecord record = records.get(0);
                record.setOrderDate(new Date());
                record.setSetmealId(weeklySetMealId);
                record.setCreateTime(new Date());
                orderRecordService.updateOrderRecord(record);
                return AjaxResult.success();
            } else if (records.size() == 2) {
                OrderRecord record = records.stream().filter(o -> Objects.equals(o.getMealType(), mealType)).collect(Collectors.toList()).get(0);
                record.setOrderDate(new Date());
                record.setSetmealId(weeklySetMealId);
                record.setCreateTime(new Date());
                orderRecordService.updateOrderRecord(record);
                return AjaxResult.success();
            } else if (records.size() > 2) {
                return AjaxResult.error("非法数据请求,当天重复报餐");
            }
        }

        //数据准备
        WeeklySetmeal selected = weeklySetmealService.selectWeeklySetmealById(weeklySetMealId);


        OrderRecord orderRecord = new OrderRecord();
        orderRecord.setUserId(userId);
        orderRecord.setMealType(selected.getMealType());
        orderRecord.setQuantity(1L);
        orderRecord.setStatus("已报餐");
        orderRecord.setOrderDate(new Date());
        orderRecord.setWeekday(weekDay);
        orderRecord.setWeekNumber(dayNumber);
        orderRecord.setSetmealId(weeklySetMealId);
        orderRecord.setCreateTime(new Date());
        orderRecordService.insertOrderRecord(orderRecord);
        return AjaxResult.success();
    }

    private int checkCount(Long userId) {
        return mainMapper.checkCount(userId);
    }

    @PostMapping("/cancelOrder")
    public AjaxResult cancelOrder(@RequestBody Map<String, String> params, HttpServletRequest request) {
        Long weeklySetMealId = Long.valueOf(params.get("packageId"));
        Long userId = Long.valueOf(params.get("userId"));
        String mealType = params.get("mealType");
        Long dayNumber = Long.valueOf(params.get("dayNumber"));
        if (checkCancelCondition(dayNumber, mealType) == 0) {
            return AjaxResult.error("当前时间不可取消报餐");
        }
        OrderRecord record = orderRecordService.selectOrderRecordByDto(userId, mealType, dayNumber, weeklySetMealId);
        if (record != null && !Objects.equals(record.getStatus(), "已领取")) {
            orderRecordService.deleteOrderRecordById(record.getId());
        }
        return AjaxResult.success();
    }

    public int checkCancelCondition(Long dayNumber, String mealType) {
        LocalDate today = LocalDate.now();
        LocalDate mealDate = LocalDate.parse(dayNumber.toString(), DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 获取当前时间
        LocalTime now = LocalTime.now();

        // 从数据库读取取消截止时间，假设返回字符串格式如 "12:00"
        String deadlineStr = getConfigValue("cancel_deadline_time");
        LocalTime deadlineTime = LocalTime.parse(deadlineStr); // 例如 "12:00"

        if (mealDate.isAfter(today.plusDays(1))) {
            // 后天及以后
            return 1;
        } else if (mealDate.isEqual(today.plusDays(1))) {
            // 明天
            if (now.isBefore(deadlineTime)) {
                return 1;
            } else {
                return 0;
            }
        } else {
            // 今天或更早
            return 0;
        }
    }

    public String getConfigValue(String key) {
        // 使用 Redis 缓存
        String value = redisCache.getCacheObject(key);
        if (value == null || StringUtils.isEmpty(value)) {
            // 如果 Redis 中没有找到，从数据库读取并设置到 Redis 中
            value = mainMapper.getValueByKey(key);
            if (value != null && !StringUtils.isEmpty(value)) {
                redisCache.setCacheObject(key, value, 1, TimeUnit.DAYS);
            } else {
                value = "12:00"; // 设置默认值
            }
        }
        return value;
    }

    @PostMapping("/hxz/v1/ConsumTransactions")
    public ResponseEntity<Map<String, Object>> processConsumTransaction(@RequestBody ConsumTransaction consumTransaction) {
        // 1. 获取请求参数
        String order = consumTransaction.getOrder();
        String cardNo = consumTransaction.getCardNo();
        Integer cardMode = consumTransaction.getCardMode();//卡模式（0：实体卡 1：电子卡）
        Integer mode = consumTransaction.getMode();//交易模式（0:刷卡扣费 1：现金充值2：余额查询 3:钱包转账 4:现金退款）
        Integer payType = consumTransaction.getPayType();//扣费类型（0:手动 1：菜单 2：定值 3：取餐 4：计时 5：计次）
        String amount = consumTransaction.getAmount();
        List<ConsumTransaction.Menu> menus = consumTransaction.getMenus();

        // 获取当前时间
        LocalTime now = LocalTime.now();
        String mealType = null;
        if (now.isAfter(LocalTime.of(11, 0)) && now.isBefore(LocalTime.of(14, 0))) {
            mealType = "午餐";
        } else if (now.isAfter(LocalTime.of(16, 0)) && now.isBefore(LocalTime.of(21, 0))) {
            mealType = "晚餐";
        }

        // 获取当前年月日（格式：20250411）
        LocalDate today = LocalDate.now();
        String dateStr = today.format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 获取当前星期（格式：星期五）
        DayOfWeek dayOfWeek = today.getDayOfWeek();
        String weekStr = dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.CHINA);

        // 查询是否已消费
        OrderRecord orderRecord = orderRecordService.selectOrderRecordByCarNo(cardNo, mealType, dateStr, weekStr);
        if (orderRecord == null) {
            Map<String, Object> failResponse = new HashMap<>();
            failResponse.put("Status", 0);
            failResponse.put("Msg", "该卡今天" + mealType + "未报餐！");
            return ResponseEntity.ok(failResponse);
        } else if (Objects.equals(orderRecord.getStatus(), "已领取")) {
            Map<String, Object> failResponse = new HashMap<>();
            failResponse.put("Status", 0);
            failResponse.put("Msg", "该卡今天" + mealType + "重复刷卡取餐！");
            return ResponseEntity.ok(failResponse);
        }
        SysUser user = userService.selectUserByCarNo(cardNo);
        if (orderRecord.getMealType().equals(mealType)) {
            orderRecord.setStatus("已领取");
            orderRecordService.updateOrderRecord(orderRecord);
            System.out.println("----------------------" + user.getCount());
            userService.updateUserCount(user.getUserId(), user.getCount() - 1);
        }
        // 构造返回数据
        Map<String, Object> response = new HashMap<>();
        response.put("Status", 1);
        response.put("Msg", "核销成功:" + mealType);
        response.put("Name", user.getNickName());
        response.put("CardNo", user.getCardNo());
        response.put("Money", 0);
        response.put("Subsidy", 0.00);
        response.put("Times", user.getCount() - 1);
        response.put("Integral", 0.00);
        response.put("InTime", "");
        response.put("OutTime", "");
        response.put("CumulativeTime", "");
        response.put("Amount", amount);
        response.put("VoiceID", mealType + "核销成功");
        response.put("Text", user.getNickName() + ":" + mealType + "核销成功");

        return ResponseEntity.ok(response);
    }

    @GetMapping("/canteen/dish/getDishList")
    public TableDataInfo getDishList(Setmeal setmeal) {
        List<MealListVo> list = setmealService.getDishList();
        return getDataTable(list);
    }

    @PostMapping("/websocket/sendMesg")
    public AjaxResult sendMsg(@RequestBody Map<String, String> payload) {
        String userId = payload.get("userId");
        String message = payload.get("message");
        WebSocketServer.sendMessageToUser(userId, message);
        return AjaxResult.success();
    }

    @PostMapping("/websocket/sendMesgAll")
    public AjaxResult sendMsgAll(@RequestBody Map<String, String> payload) throws IOException {
        String message = payload.get("message");
        WebSocketServer.sendMessage(message, new HashSet<>());
        return AjaxResult.success();
    }

    @PostMapping("/mealRecords")
    public AjaxResult mealRecords(@RequestBody Map<String, String> param) {
        String startDate = param.get("startDate");
        String endDate = param.get("endDate");
        String weekday = param.get("weekday");
        try {
            List<MealRecordDTO> result = orderRecordService.queryChartByDate(
                    startDate, endDate, weekday
            );
            System.out.println(result);
            return AjaxResult.success(result);
        } catch (IllegalArgumentException e) {
            return AjaxResult.error(e.getMessage());
        } catch (Exception e) {
            return AjaxResult.error("系统异常，请稍后再试");
        }
    }

    @GetMapping("/canteen/getCarouselByWeeklyMealId/{id}")
    public AjaxResult getCarouselByWeeklyMealId(@PathVariable Integer id) {
        LocalDateTime now = LocalDateTime.now();
        DayOfWeek dayOfWeek = now.getDayOfWeek();

        // 特殊处理：如果是周六，往前调一天；如果是周日，往后调一天
        if (dayOfWeek == DayOfWeek.SATURDAY) {
            now = now.minusDays(1);
        } else if (dayOfWeek == DayOfWeek.SUNDAY) {
            now = now.plusDays(1);
        }

        String dateStr = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        int dateInt = Integer.parseInt(dateStr);

        // 判断是午餐还是晚餐
        int hour = now.getHour();
        String mealType = (hour >= 8 && hour < 14) ? "午餐" : "晚餐";

        // 根据 ID 获取套餐标识
        String mealMark;
        switch (id) {
            case 1:
                mealMark = "套餐A";
                break;
            case 2:
                mealMark = "套餐B";
                break;
            case 3:
                mealMark = "套餐C";
                break;
            default:
                mealMark = "未知套餐";
        }

        // 特殊逻辑：14点后且不是套餐A，改为午餐
        if (hour >= 14 && id != 1) {
            mealType = "午餐";
        }
        CarouseDto dto = weeklySetmealService.getCarousel(dateInt, mealType, mealMark);
        return AjaxResult.success(dto);
    }
    //就餐信息接口
    @GetMapping("/mealRecords/statistics")
    public AjaxResult getMealStatistics(@RequestParam("orderDate") Integer orderDate) {
        List<MealStatisticsVO> result = mealStatistics(orderDate);
        return AjaxResult.success(result);
    }

    public List<MealStatisticsVO> mealStatistics(Integer orderDate) {
        return mainMapper.getMealStatistics(orderDate);
    }
    //每日就餐详情接口
// 在Controller中添加
    @GetMapping("/mealRecords/details")
    public AjaxResult getMealDetails(
            @RequestParam("orderDate") Integer orderDate,
            @RequestParam("mealType") String mealType,
            @RequestParam("status") String status) {

        List<MealDetailVO> details = mainMapper.getMealDetails(orderDate, mealType, status);
        return AjaxResult.success(details);
    }


}


